#include <QWidget>
#include <QSlider>
#include <QGridLayout>
#include <QCloseEvent>
#include <QIcon>

#include "wdet.h"
#include "see.h"
#include "canvaspicker.h"

#include <qevent.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_curve.h>
#include <qwt_symbol.h>
#include <qwt_scale_widget.h>
#include <qwt_scale_engine.h>
#include <qwt_wheel.h>
#include <stdlib.h>
#include <vector>
#include <iostream>

#include "globalconstants.h"

using namespace std;


pDetector::pDetector(QWidget *parent) : QwtPlot(parent),
    zeroCu(0),
    totCu(0),
    thr2Cu(0),
    thr1Cu(0)
{
  enableAxis(0,0);
  enableAxis(2,0);
    //axisScaleEngine(0)->setMargins(0, 0);
    //axisScaleEngine(2)->setMargins(0, 0);
    //setCanvasColor(Qt::white); //queda!!!!!!!!!!!!

    // Avoid jumping when label with 3 digits
    // appear/disappear when scrolling vertically

  QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
  sd->setMinimumExtent( sd->extent(QPen(),axisWidget(QwtPlot::yLeft)->font()));

  plotLayout()->setAlignCanvasToScales(true);

  zeroCu = new QwtPlotCurve();
  zeroCu->setPen(Qt::NoPen);
  zeroCu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,Qt::white, Qt::SolidLine, QSize(5, 5)));
  zeroCu->attach(this);
    
  totCu = new QwtPlotCurve();
  totCu->setPen(Qt::NoPen);
  totCu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorToT, Qt::NoPen, QSize(10, 10)));
  totCu->attach(this);
    
  thr2Cu = new QwtPlotCurve();
  thr2Cu->setPen(Qt::NoPen);
  thr2Cu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorThr2, Qt::NoPen, QSize(10, 10)));
  thr2Cu->attach(this);
    
  thr1Cu = new QwtPlotCurve();
  thr1Cu->setPen(Qt::NoPen);
  thr1Cu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorThr1, Qt::NoPen, QSize(8, 8)));
  thr1Cu->attach(this);
}

pDetector::pDetector(vector<tStation>* statList,QWidget *parent) : QwtPlot(parent),
    zeroCu(0),
    totCu(0),
    thr2Cu(0),
    thr1Cu(0)
{
    enableAxis(0,0);
    enableAxis(2,0);
    //axisScaleEngine(0)->setMargins(0, 0);
    //axisScaleEngine(2)->setMargins(0, 0);
    //setCanvasColor(Qt::white); //queda!!!!!!!!!!!!

    // Avoid jumping when label with 3 digits
    // appear/disappear when scrolling vertically

    QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
    sd->setMinimumExtent( sd->extent(QPen(),axisWidget(QwtPlot::yLeft)->font()));

    plotLayout()->setAlignCanvasToScales(true);

    zeroCu = new QwtPlotCurve();
    zeroCu->setPen(Qt::NoPen);
    zeroCu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,Qt::white, Qt::SolidLine, QSize(5, 5)));
    zeroCu->attach(this);
    
    totCu = new QwtPlotCurve();
    totCu->setPen(Qt::NoPen);
    totCu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorToT, Qt::NoPen, QSize(10, 10)));
    totCu->attach(this);
    
    thr2Cu = new QwtPlotCurve();
    thr2Cu->setPen(Qt::NoPen);
    thr2Cu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorThr2, Qt::NoPen, QSize(10, 10)));
    thr2Cu->attach(this);
    
    thr1Cu = new QwtPlotCurve();
    thr1Cu->setPen(Qt::NoPen);
    thr1Cu->setSymbol(QwtSymbol(QwtSymbol::Ellipse,colorThr1, Qt::NoPen, QSize(8, 8)));
    thr1Cu->attach(this);

    paintDetector(statList);
}

void pDetector::setCanvasColor(const QColor &c)
{
    setCanvasBackground(c);
    replot();
}

bool pDetector::eventFilter(QObject *object, QEvent *e)
{
    return QwtPlot::eventFilter(object, e);
}

void pDetector::externalTankSelect(int sId, eLT lt)
{
  QwtPlotCurve* curve;
  int index=-1;
  //cout << "\nseleccoin externa\n";
  switch (lt) {
    case eToT:
      curve=totCu;
      for(int i=0;i<totIndex.size();i++){
        if(totIndex[i]==sId){
          index=i;
          break;
        }
      }
      break;
    case eThr2:
      curve=thr2Cu;
      for(int i=0;i<thr2Index.size();i++){
        if(thr2Index[i]==sId){
          index=i;
          break;
        }
      }
      break;
    case eThr1:
      curve=thr1Cu;
      for(int i=0;i<thr1Index.size();i++){
        if(thr1Index[i]==sId){
          index=i;
          break;
        }
      }
      break;
  }
  
  if(index==-1) return;
  
  emit newTankId(curve,index);
}

void pDetector::selectTank(int curveId,int index)
{
  switch (curveId) {
    case 0:
      //cout << "\nTomando del indiceZero el item: "<<index<<endl;
      emit changedTank(zeroIndex[index]);
      break;
    case 1:
      //cout << "\nTomando del indiceToT el item: "<<index<<endl;
      emit changedTank(totIndex[index]);
      break;
    case 2:
      //cout << "\nTomando del indiceThr2 el item: "<<index<<endl;
      emit changedTank(thr2Index[index]);
      break;
    case 3:
      //cout << "\nTomando del indiceThr1 el item: "<<index<<endl;
      emit changedTank(thr1Index[index]);
      break;
  }
}

void pDetector::paintDetector(vector<tStation>* statList)
{
  vector<double> xZero;
  vector<double> yZero;
  
  vector<double> xTot;
  vector<double> yTot;
  
  vector<double> xThr2;
  vector<double> yThr2;
  
  vector<double> xThr1;
  vector<double> yThr1;
  
  zeroIndex.clear();
  totIndex.clear();
  thr2Index.clear();
  thr1Index.clear();
  
  setAxisAutoScale(0);
  setAxisAutoScale(2);
  
  for(int i=0;i<statList->size();i++){
    
    switch (statList->at(i).lt) {
      case eToT:
        totIndex.push_back(statList->at(i).sId);
        xTot.push_back(statList->at(i).x);
        yTot.push_back(statList->at(i).y);
        break;
      case eThr2 :
        thr2Index.push_back(statList->at(i).sId);
        xThr2.push_back(statList->at(i).x);
        yThr2.push_back(statList->at(i).y);
        break;
      case eThr1 : 
        thr1Index.push_back(statList->at(i).sId);
        xThr1.push_back(statList->at(i).x);
        yThr1.push_back(statList->at(i).y);
        break;
      default:
        zeroIndex.push_back(statList->at(i).sId);
        xZero.push_back(statList->at(i).x);
        yZero.push_back(statList->at(i).y);
    }
  }
  
  zeroCu->setData(&xZero[0],&yZero[0], xZero.size());
  totCu->setData(&xTot[0],&yTot[0], xTot.size());
  thr2Cu->setData(&xThr2[0],&yThr2[0], xThr2.size());
  thr1Cu->setData(&xThr1[0],&yThr1[0], xThr1.size());
  replot();
}


wDet::wDet(QWidget *parent)
{
  setWindowTitle("Detector");
  setWindowIcon(QIcon(iconDet));
  detPlot=new pDetector();
  (void) new CanvasPicker(detPlot);
  
  minX=detPlot->axisScaleDiv(2)->lBound();
  maxX=detPlot->axisScaleDiv(2)->hBound();
  minY=detPlot->axisScaleDiv(0)->lBound();
  maxY=detPlot->axisScaleDiv(2)->hBound();
  
  xDetMean=(maxX+minX)/2.;
  yDetMean=(maxY+minY)/2.;
  
  xMean=xDetMean;
  yMean=yDetMean;
  
  xMaxRadio=(xMean-minX) > (maxX- xMean) ? (xMean-minX) : (maxX- xMean);
  yMaxRadio=(yMean-minY) > (maxY- yMean) ? (yMean-minY) : (maxY- yMean);
  
  xRadio=xMaxRadio*1.1;
  yRadio=yMaxRadio*1.1;
  
  zoom=new QSlider();
  zoom->setRange(10,100);
  zoom->setValue(100);
  
  hRuedita=new QwtWheel();
  hRuedita->setRange(0.5,1.5);
  hRuedita->setValue(1);
  
  vRuedita=new QwtWheel();
  vRuedita->setOrientation(Qt::Vertical);
  vRuedita->setRange(0.5,1.5);
  vRuedita->setValue(1);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(detPlot,0,1,4,4);
  layout->addWidget(zoom,2,0,3,0);
  layout->addWidget(hRuedita,5,3);
  layout->addWidget(vRuedita,3,5);
  layout->setRowStretch(1, 10);
  layout->setColumnStretch(1, 10);
  layout->setColumnStretch(0, 1);
  layout->setRowStretch(4, 0);
  setLayout(layout);
  
  QObject::connect(hRuedita,SIGNAL(valueChanged(double)),this,SLOT(moveHPlot(double)));
  QObject::connect(vRuedita,SIGNAL(valueChanged(double)),this,SLOT(moveVPlot(double)));
  QObject::connect(zoom,SIGNAL(valueChanged(int)),this,SLOT(rescalePlot(int)));
  
  QObject::connect(this,SIGNAL(paintDetector(vector<tStation>*)),detPlot,SLOT(paintDetector(vector<tStation>*)));
  QObject::connect(this,SIGNAL(externalTankSelect(int,eLT)),detPlot,SLOT(externalTankSelect(int,eLT)));
  QObject::connect(detPlot,SIGNAL(changedTank(int)),this,SIGNAL(changedTank(int)));
  
  zoom->setValue(60);
  rescalePlot(60);
}

wDet::wDet(vector<tStation>* statList,QWidget *parent)
{
  setWindowTitle("Detector");
  setWindowIcon(QIcon(iconDet));
  detPlot=new pDetector(statList);
  (void) new CanvasPicker(detPlot);
  
  minX=detPlot->axisScaleDiv(2)->lBound();
  maxX=detPlot->axisScaleDiv(2)->hBound();
  minY=detPlot->axisScaleDiv(0)->lBound();
  maxY=detPlot->axisScaleDiv(2)->hBound();
  
  xDetMean=(maxX+minX)/2.;
  yDetMean=(maxY+minY)/2.;
  
  xMean=xDetMean;
  yMean=yDetMean;
  
  xMaxRadio=(xMean-minX) > (maxX- xMean) ? (xMean-minX) : (maxX- xMean);
  yMaxRadio=(yMean-minY) > (maxY- yMean) ? (yMean-minY) : (maxY- yMean);
  
  xRadio=xMaxRadio*1.1;
  yRadio=yMaxRadio*1.1;
  
  zoom=new QSlider();
  zoom->setRange(10,100);
  zoom->setValue(100);
  
  hRuedita=new QwtWheel();
  hRuedita->setRange(0.5,1.5);
  hRuedita->setValue(1);
  
  vRuedita=new QwtWheel();
  vRuedita->setOrientation(Qt::Vertical);
  vRuedita->setRange(0.5,1.5);
  vRuedita->setValue(1);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(detPlot,0,1,4,4);
  layout->addWidget(zoom,2,0,3,0);
  layout->addWidget(hRuedita,5,3);
  layout->addWidget(vRuedita,3,5);
  layout->setRowStretch(1, 10);
  layout->setColumnStretch(1, 10);
  layout->setColumnStretch(0, 1);
  layout->setRowStretch(4, 0);
  setLayout(layout);
  
  QObject::connect(hRuedita,SIGNAL(valueChanged(double)),this,SLOT(moveHPlot(double)));
  QObject::connect(vRuedita,SIGNAL(valueChanged(double)),this,SLOT(moveVPlot(double)));
  QObject::connect(zoom,SIGNAL(valueChanged(int)),this,SLOT(rescalePlot(int)));
  
  QObject::connect(this,SIGNAL(paintDetector(vector<tStation>*)),detPlot,SLOT(paintDetector(vector<tStation>*)));
  QObject::connect(this,SIGNAL(externalTankSelect(int,eLT)),detPlot,SLOT(externalTankSelect(int,eLT)));
  QObject::connect(detPlot,SIGNAL(changedTank(int)),this,SIGNAL(changedTank(int)));
  
  zoom->setValue(60);
  rescalePlot(60);
}

void wDet::moveHPlot(double value)
{
  xMean=xDetMean*value;
  detPlot->setAxisScale(2,xMean-xRadio,xMean+xRadio);
  detPlot->replot();
}

void wDet::moveVPlot(double value)
{
  yMean=yDetMean*value;
  detPlot->setAxisScale(0,yMean-yRadio,yMean+yRadio);
  detPlot->replot();
}

void wDet::rescalePlot(int value)
{
  double zoomFrac=value/100.;
  xRadio=xMaxRadio*zoomFrac;
  yRadio=yMaxRadio*zoomFrac;
  detPlot->setAxisScale(0,yMean-yRadio,yMean+yRadio);
  detPlot->setAxisScale(2,xMean-xRadio,xMean+xRadio);
  detPlot->replot();
}

void wDet::newDetector(vector<tStation>* statList)
{
  emit paintDetector(statList);
  
  minX=detPlot->axisScaleDiv(2)->lBound();
  maxX=detPlot->axisScaleDiv(2)->hBound();
  minY=detPlot->axisScaleDiv(0)->lBound();
  maxY=detPlot->axisScaleDiv(2)->hBound();
  
  xDetMean=(maxX+minX)/2.;
  yDetMean=(maxY+minY)/2.;
  
  xMean=xDetMean;
  yMean=yDetMean;
  
  xMaxRadio=(xMean-minX) > (maxX- xMean) ? (xMean-minX) : (maxX- xMean);
  yMaxRadio=(yMean-minY) > (maxY- yMean) ? (yMean-minY) : (maxY- yMean);
  
  xRadio=xMaxRadio;
  yRadio=yMaxRadio;
  
  
  zoom->setValue(60);
  rescalePlot(60);
}

void wDet::tankSelect(int sId,eLT lt)
{
  emit externalTankSelect(sId,lt);
}

void wDet::closeEvent(QCloseEvent *event)
{
  emit openWindow(false);
}
